<script setup>
import {util} from 'framework'
import {message, loading} from 'heyui'
import axios from 'axios'
import {reactive} from 'vue'

/**
 * 文件导入
 *    前端用法：
 *    <FileImport to="xxx/import">
 *       <Button icon="jeicon-upload" color="primary">导入文件</Button>
 *    </FileImport>
 *    后端示例：
 *     @PostMapping("xx/import")
 *     public SseEmitter importFile(@RequestParam("file") MultipartFile file,QueryParams query) {
 *         //query-回传参数
 *         UserInfo user=Current.user();
 *         return FrontendProcess.create(p -> {
 *                 p.info("文件上传完成，导入中...");
 *                 ExcelBatchImporter<ExpendRecordImportVo> bi = new ExcelBatchImporter(file.getInputStream(), ExpendRecordImportVo.class);
 *                 bi.start((list, idx) -> {
 *                    //list就是处理好的数据列表
 *                 });
 *                 p.info("导入完成...");
 *         });
 *    }
 *
 *     @Data
 *     //指定起始行
 *     @ExcelTemplate(startRow = 2)
 *     public static class ExpendRecordImportVo {
 *         //指定字段列
 *         @Excel(columnName = "A")
 *         private String projectName;
 *    }
 */


const emit = defineEmits(['finished','error'])
const props = defineProps({
  to: {
    type: String,
    description: '导入路径'
  },
  params:{
    type: Object,
    description:'参数',
    default:{},
  }
})
const dlg = reactive({open: false})
const doImport = (f) => {
  if (f.type != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
    message("请选择Excel文件")
    return
  }
  let data = new FormData()
  data.append("file", f)
  Object.keys(props.params).forEach(k=>{
    data.append(k,props.params[k])
  })
  dlg.open = true
  dlg.info = ''
  dlg.process = 0
  dlg.finish = false
  dlg.title = '文件上传中...'
  dlg.color = 'primary'
  axios({
    url: props.to,
    data: data,
    method: 'POST',
    onUploadProgress: progressEvent => {
      dlg.title = '文件上传中...'
      if (progressEvent.loaded == progressEvent.total) {
      } else {
        let complete = (progressEvent.loaded / progressEvent.total * 100 | 0)
        // loading('文件上传中 ' + complete);
        dlg.process = complete
        dlg.info = '文件上传中...'
        if (dlg.process >= 100) {
          dlg.info = '文件上传完成'
          dlg.process = 0
        }
      }
    },
    onDownloadProgress: util.onProcessSse(e => {
      if (dlg.finish) {
        return
      }
      dlg.title = '文件导入中...'
      let rep = JSON.parse(e.data);
      switch (rep.type) {
        case "error":
          dlg.color = 'red'
          dlg.info = rep.data
          dlg.finish = true
          if (dlg.process == 0) {
            dlg.process = 100
          }
          emit('error', dlg)
          break;
        case "info":
          dlg.info = rep.data
          break;
        case "process":
          dlg.process = rep.data
          break;
        case "finish":
          dlg.title = '文件导入完成'
          dlg.process = 100
          dlg.finish = true;
          emit('finished', dlg)
          break;
      }
      //dlg.info=e.data
    })
  }).then(_ => {
    if (!dlg.finish) {
      dlg.finish = true
      dlg.process = 100
      dlg.title = '文件导入完成'
      dlg.color = 'green'
      emit('finished',dlg)
    }
  }).catch(e => {
    dlg.title = '文件导入失败'
    dlg.color = 'red'
    dlg.info = e
    dlg.finish = true
    emit('error', dlg)
  })
}
</script>

<template>
  <FileInput accept="*.xlsx" @change="doImport">
    <slot/>
  </FileInput>
  <Modal v-model="dlg.open" :closeOnMask="false" middle>
    <div style="width: 60vw;text-align: center;">
      <h3 style="padding-bottom: 10px;"> {{ dlg.title }}</h3>
      <Progress :percent="dlg.process" :color="dlg.color"></Progress>
      <div style="padding-top: 5px;margin-top:10px;text-align: left;max-height: 30vh;overflow-y: auto;">
        <div v-html="dlg.info"></div>
      </div>
    </div>
    <template #footer>
      <Button :disabled="!dlg.finish" color="primary" @click="dlg.open=false">确认</Button>
    </template>
  </Modal>
</template>
